package org.facyt.vacas.services.impl;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.facyt.vacas.dto.ComponeteVectorX;
import org.facyt.vacas.dto.DatosDTO;
import org.facyt.vacas.dto.ItemFO;
import org.facyt.vacas.dto.MpDTO;
import org.facyt.vacas.entities.vacas.Alimento;
import org.facyt.vacas.entities.vacas.Componente;
import org.facyt.vacas.entities.vacas.ComponenteValor;
import org.facyt.vacas.entities.vacas.MateriaPrima;
import org.facyt.vacas.entities.vacas.restricciones.Igual;
import org.facyt.vacas.entities.vacas.restricciones.MayorIgual;
import org.facyt.vacas.entities.vacas.restricciones.MenorIgual;
import org.facyt.vacas.entities.vacas.restricciones.Restriccion;
import org.facyt.vacas.entities.vacas.restricciones.RestriccionDoble;
import org.facyt.vacas.entities.vacas.restricciones.RestriccionFactorAjuste;
import org.facyt.vacas.entities.vacas.restricciones.RestriccionRango;
import org.facyt.vacas.entities.vacas.restricciones.RestriccionSimple;
import org.facyt.vacas.services.AnimalService;
import org.facyt.vacas.services.ComponenteService;
import org.facyt.vacas.services.ExceptionAplicacion;
import org.facyt.vacas.services.FormulacionService;
import org.facyt.vacas.services.MateriasPrimasService;
import org.facyt.vacas.services.ProcesarService;
import org.facyt.vacas.services.RequerimientosService;
import org.facyt.vacas.util.Constantes;
import org.facyt.vacas.utils.LeerArchivo;
import org.facyt.vacas.utils.RecuentoDatos;
import org.facyt.vacas.utils.StringUtils;
import org.facyt.vacas.utils.UtilsFormulRecuento;
import org.springframework.beans.factory.ListableBeanFactory;


public class FormulacionServiceImpl implements FormulacionService {
	
	private MateriasPrimasService mpService;
	private RequerimientosService reqService;
	private ProcesarService procesarService;
private AnimalService animalService;
private ComponenteService componenteService;
	
	
	public ComponenteService getComponenteService() {
	return componenteService;
}

public void setComponenteService(ComponenteService componenteService) {
	this.componenteService = componenteService;
}

	public AnimalService getAnimalService() {
		return animalService;
	}

	public void setAnimalService(AnimalService animalService) {
		this.animalService = animalService;
	}

	public MateriasPrimasService getMpService() {
		return mpService;
	}

	public void setMpService(MateriasPrimasService mpService) {
		this.mpService = mpService;
	}

	public RequerimientosService getReqService() {
		return reqService;
	}

	public void setReqService(RequerimientosService reqService) {
		this.reqService = reqService;
	}

	public ProcesarService getProcesarService() {
		return procesarService;
	}

	public void setProcesarService(ProcesarService procesarService) {
		this.procesarService = procesarService;
	}

	/**
	 * variables
	 */
	private static ArrayList listaRequerimientosParaFormular = null;
//	private static RecuentoDatos ultimoResultadoFormulacion = null;
	private static int procesamiento = 1;
	private static Vector filaVariablesMpcodigo = null;
	private static int m11 = 0;
	private static int m22 = 0;
	private static int m33 = 0;
	private static String mensaje;
	
	public static final BigDecimal ONEHUNDERT = new BigDecimal(100);
	
	public BigDecimal cms = BigDecimal.ZERO;

	
	public BigDecimal getCms() {
		return cms;
	}

	public void setCms(BigDecimal cms) {
		this.cms = cms;
	}

	public void Formular(){
		
		
	}
	
	public void main (String[] args)
	{
		 FormulacionServiceImpl f = new FormulacionServiceImpl();
		 
		 DatosDTO d = new DatosDTO(1);
		 ArrayList<MpDTO> lista = new ArrayList<MpDTO>();
		 //alfalfa id=125
		 //10 gr
		 
		MateriaPrima mp = null;
		try {
			mp = mpService.getMateriaPrimaById(125);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		 MpDTO mpdto = new MpDTO(BigDecimal.valueOf(10));
		 mpdto.setMp(mp);
		 lista.add(mpdto);
		try{
		 
		 f.formular(lista, d, null, null);
		
		}catch (Exception e) {
			// TODO: handle exception
		}
		
	}
	
private List<Restriccion> generarRequerimientoNRC(DatosDTO d, ArrayList<MpDTO> lista) {
		
	List<Restriccion> reqNrc = new ArrayList<Restriccion>();
		
		try{
			
			reqNrc = procesarService.procesar(d, lista);
			
			
		}catch (Exception e) {
			
			return null;
		}
		
		return reqNrc;
	}
	

	/**
	 * Este metodo recibira los datos de la pantalla y los requerimientos, con todo esto procesara
	 * los datos para obtener el optimo. 
	
	 * @param lista: lista de mp y cantidad de cada una
	 * @param usuario: el id del grupo del usuario
	 * @param datosDTO lista de datos
	 * @param hash
	 * @param urlJasper
	 * @return
	 * @throws Exception
	 */
	public void formular(
			ArrayList<MpDTO> lista,
			// UsuarioDTO usuario,
			DatosDTO datosDTO,
			 Map hash, URI urlJasper) throws Exception {

		//pasar los datos numericos obtenidos en el proceso a restricciones.
		//btengo los requerimientos nrc segun proceso sql
		ArrayList<Restriccion> listRestricciones = (ArrayList<Restriccion>) generarRequerimientoNRC(datosDTO, lista);
		
		//seteo el cms obtenido segun nrc
		setCms(datosDTO, listRestricciones);
		
		//genero los reuqerimientos en base a las ecuaciones incorporadas a la base.
		listaRequerimientosParaFormular = armarRequerimientosParaFormular(datosDTO.getIdtipoanimal());//,listamodificadas);
		
		try{
			

		
		//pasar las restricciones a una matriz de tipo simplex
		ArrayList l = getMatriz(lista);
		
		//copiar las restriciones obtenidas a una lista unica.
		ArrayList<Vector> restriccionesLista = new ArrayList<Vector>();
		for (int h = 0; h < l.size(); h++) {
			restriccionesLista.add((Vector) l.get(h));
		}
		
		//generar las funcion objetivo de la matriz simplex
		Vector fo = generarFo(lista);
		
		//obtener ls restricciones sobre ls mp que propone el usuario
		Vector restriccionesMP = getRestriccionesMP(lista, datosDTO.getPv());
		
		// corre el primer cosmin, para satisfacer los requerimientos  del usuario

		//this.ultimoResultadoFormulacion = null;
		resetProcesamiento();
		
		Vector vector = procesarRequerimiento(restriccionesLista,
				fo, restriccionesMP, lista);
		
		aumentarProcesamiento();
		
		
		if (vector != null && vector.size() > 0) {
			// si se obtubo resultado, y este es solucion a la formulacion.?
			String icaseString = (String) vector.get(0);
			icaseString = StringUtils
					.quitarEspaciosAdelanteYAtras(icaseString);
			int icase = new Integer(icaseString).intValue();
			// si icase < 0 significa que no se pudo formular.
			if (icase < 0) {
				// no hay solucion.
				String mensaje = "Las materias primas disponibles no pueden satisfacer los requerimientos nutricionales del alimento.";
				throw new ExceptionAplicacion(mensaje,
						Constantes.TipoException.INFORMACION);
			} else {
				
				//TODO: leer la solucion.
				
				obtenerResultado(vector, lista, null);
				
			}
		} else {
			// si el vector resultaod es null significa que no se pudo
			// formular.
			// no hubo solucion
			
			String mensaje = "Las materias primas disponibles no pueden satisfacer los requerimientos nutricionales del alimento.";
			throw new ExceptionAplicacion(mensaje,
					Constantes.TipoException.INFORMACION);
		}
		} catch (ExceptionAplicacion e) {
			
			System.out.println("error ");
			if (mensaje != null)
				throw new ExceptionAplicacion(mensaje,
						Constantes.TipoException.ERROR);
			else
				throw e;
		} catch (Exception e) {
				
			System.out.println("error ");
			if (mensaje != null)
				throw new ExceptionAplicacion(mensaje,
						Constantes.TipoException.ERROR);
			else
				throw e;
		}

	

}

	private void setCms(DatosDTO datosDTO, ArrayList<Restriccion> listarequerimientos) {
		
		try {
		BigDecimal pv = datosDTO.getPv();
		Componente compoCMS;
		
			compoCMS = componenteService.getComponenteById(Constantes.componente.CMS);
		
		
		
		Iterator iterador = listarequerimientos.iterator();
		Restriccion rs = null;
		Componente c;
		boolean encontrado = false;
		while (iterador.hasNext() && !encontrado) {
			Restriccion r = (Restriccion) iterador.next();

			if (r.esSimple()) {
				c = ((Componente) ((org.facyt.vacas.entities.vacas.restricciones.RestriccionSimple) r).getComponenteById());
				
				if (c.equals(compoCMS)) {
					rs = (Restriccion) r;
					encontrado = true;
				}

			}
		}
		if(rs!= null)
			setCms(((RestriccionSimple)rs).getCantidad());
		else
			setCms(BigDecimal.ZERO);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void setCms(DatosDTO datosDTO) {
		// TODO VER en este caso en que genraria un rango de valor de cms.
		
		try {
			BigDecimal pv = datosDTO.getPv();
			Componente c = componenteService.getComponenteById(Constantes.componente.CMS);
			
			Alimento alimento = animalService.getAnimalByIdCompleto(new Integer(datosDTO.getIdtipoanimal()).longValue());
			RestriccionRango r = (RestriccionRango) alimento.getRestriccionRango((ArrayList<Restriccion>)alimento.getRequerimientos(), c);
			
			BigDecimal max = r.getValorMax();
			BigDecimal min = r.getValorMin();
			
			
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	private ArrayList armarRequerimientosParaFormular(int idanimal){	//,List<FormulacionDTO> listaRestriccionesModificadas
	
		long id = new Integer(idanimal).longValue(); 
		
		Alimento animal = getAlimento(id);
		ArrayList lrestricciones = new ArrayList();
		
		//Obtengo la lista de requerimientos del animal seleccionado desde la base, lo clono		
		Iterator iter = null;
		try {
			lrestricciones = getRequerimientosClone(animal);
			iter = lrestricciones.iterator();
		} catch (Exception e) {
			// TODO: handle exception
			System.err.println("Error");
		}
		return lrestricciones;
	}
	
	public ArrayList<Restriccion> getRequerimientosClone(Alimento alimento) {
		ArrayList<Restriccion> l = new ArrayList<Restriccion>();
		Iterator iterador = new ArrayList<Restriccion>().iterator();
		try {
			alimento = animalService.getAnimalByIdCompleto(alimento.getId());
		} catch (Exception e) {
			System.err.println("Error");
		}
		iterador = alimento.getRequerimientos().iterator();
		while (iterador.hasNext()) {
			Restriccion req = (Restriccion) iterador.next();
			Restriccion reqClonado;
			try {
				reqClonado = (Restriccion) req.clone();
				
				if (reqClonado != null)
				{
					reqClonado.setId(req.getId());				
					l.add(reqClonado);
				}
			} catch (CloneNotSupportedException e) {

				System.err.println("Error");
			}
		}
		return l;
	}

	
	private Alimento getAlimento(long idanimal) {

		try {
			return animalService.getAnimalById(idanimal);
		} catch (Exception e) {

			System.err.println("Error");
			return null;
		}

	}
	private void obtenerResultado(Vector vector, ArrayList<MpDTO>  renglones, RecuentoDatos rdResultado) 
		// TODO generar pàra devolver el resultado

				throws ExceptionAplicacion {

			boolean imprimir = false;

			String optimoString = "";
			String hh = "";
			String cantidadVariable = "";
			String cantidadRestricciones = "";
			int n;
			int m;
			Vector a = new Vector();
			ArrayList x = new ArrayList();
			Vector iposv = new Vector();
			List listaMps = new ArrayList();
			ArrayList listado = new ArrayList();
			ArrayList listaMpsNoIntervienen = new ArrayList();
			BigDecimal cantMpAlimento = BigDecimal.ZERO;
			BigDecimal costoTotal =BigDecimal.ZERO;
			BigDecimal costoXKg =BigDecimal.ZERO;
			// hay solucion
			// leer iposv y izrov: cantidad de las mp qeu intervienen en la
			// formulacion
			// la mp que estan en la tabla y su id no esta en iposv, no imterviene.

			// leer el optimo y los valores de las variables.
			imprimir = true;

			optimoString = (String) vector.get(1);
			hh = StringUtils.quitarEspaciosAdelanteYAtras(optimoString); // leer
			// la
			// solucion.
			cantidadVariable = (String) vector.get(2);
			n = new Integer(
					StringUtils.quitarEspaciosAdelanteYAtras(cantidadVariable))
					.intValue();

			for (int u = 0; u < n; u++)
				x.add(null);

			cantidadRestricciones = (String) vector.get(3);
			m = new Integer(
					StringUtils.quitarEspaciosAdelanteYAtras(cantidadRestricciones))
					.intValue();
			Float energiaFloat;
			listaMps = new ArrayList();
			ArrayList trioMpCant;
			int i = 0;
			int var = 0;
			ArrayList listaId = new ArrayList();
			// MP que intevienen
//			float energiaTotalRespuesta = 0;
//			float cantidad = new Float(cantidadAelaborar).floatValue();

			// WriteArchivos.escribirLog("componente: Energia");
			while (i < (n * 2)) {
				ComponeteVectorX compovx = new ComponeteVectorX();
				trioMpCant = new ArrayList();
				String id = (String) vector.get(i + 4);
				String idMp = StringUtils.quitarEspaciosAdelanteYAtras(id);
				String valor = (String) vector.get(i + 5);
				String valorMp = StringUtils.quitarEspaciosAdelanteYAtras(valor);
				BigDecimal cantMPaportada = new BigDecimal(valorMp).multiply(new BigDecimal(1000));
				BigDecimal energiaRespuesta = BigDecimal.ZERO;

				int idInt = new Integer(idMp).intValue() - 1;

				// RestriccionesRecuento lis = ((ModeloTablaConsultaRestriccionesMP)
				// jTableRestricciones
				// .getModel()).getRestriccionFilaRecuento(new Integer(
				// idMp).intValue() - 1);

				
				MateriaPrima mp = null;
				
				try {
					 mp  = renglones.get(new Integer(idMp).intValue() - 1).getMp();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					System.out.println("error");
				}
				
				BigDecimal costoMPaportada = null;
				
				if(mp!= null)
				{					
					/*String renglonCosto = StringUtils.reemplazar((String) renglones.get(
							new Integer(idMp).intValue() - 1)
							.getItem(Constantes.EncabezadosRecontar.COSTO), ",",".");
					
					costoMPaportada = new Double(renglonCosto);*/
					
					costoMPaportada = renglones.get(new Integer(idMp).intValue() - 1).getCosto();
					
					//TODO: se guarda en la mp, el costo ingresado en el renglon de la tabla,
					//salvo sea 0.????????
					//mp = mpService.setearCostoMP(mp, costoMPaportada);
					
				}

				compovx.setMp(mp);
				compovx.setCantidadMp(cantMPaportada);
				x.set(idInt, compovx);

				if (cantMPaportada.compareTo(BigDecimal.ZERO) > 0) {

					listaId.add(idMp);

				/*	ComponenteValor energiacvrespuesta = materiaPrimaDao
							.getComponenteFromComposicion(mp,
									alimento.getCvenergia());
					//aca hace dividido por 1000 pues este o no el prepromic, la cantidad de formulacion es 1000.
					energiaRespuesta = UtilsFormulRecuento.multiplicar(calcularCantidadAporte(energiacvrespuesta),cantMPaportada / 1000);
							//energiacvrespuesta.getCantidad().floatValue(),cantMPaportada / 1000);
							
				*/	
					// WriteArchivos.escribirLog("mp: " + cantMPaportada + " kg de "
					// + lis.getM().getDescripcion() + ": "
					// + energiacvrespuesta.getCantidad() + " kcal/kg = "
					// + energiaRespuesta + " kcal");


					costoTotal = costoTotal.add(UtilsFormulRecuento.multiplicar(cantMPaportada,mp.getCosto()));
					
					cantMpAlimento = cantMpAlimento.add(cantMPaportada);
					
					trioMpCant.add(mp);
					trioMpCant.add(cantMPaportada);
					trioMpCant.add(mpService.getCostoXUnidadString(mp, costoMPaportada));
					
					
					listaMps.add(trioMpCant);
				}
//				energiaTotalRespuesta = energiaTotalRespuesta + energiaRespuesta;
				i = i + 2;
			}
			

			if (cantMpAlimento.compareTo(BigDecimal.ZERO) > 0)
				costoXKg = costoTotal.divide(cantMpAlimento, Constantes.presicioncosto, Constantes.redondeomode);
			else
				costoXKg = costoTotal;

		
			//TODO: generar el recuento.
			/*listado = gestorRecuento.recontarFormulacion(listaMps, new Float(
					energiaTotalRespuesta), cantMpAlimento,
					listaRequerimientosParaFormular);*/

			imprimir = true;

			// creo una lista con las mp que no intervienen.
			int columnas = renglones.size();
			for (int kk = 0; kk < columnas; kk++) {
				String kkString = new Integer(kk + 1).toString();
				if (!listaId.contains(kkString)) {
					trioMpCant = new ArrayList();

					MateriaPrima mp = null;
					try {
						mp = renglones.get(kk).getMp();
					} catch (Exception e) {
						// TODO Auto-generated catch block
						System.out.println("errror");
					}
					
					BigDecimal costoMPaportada = mp.getCosto();
					
					if(mp!= null)
					{					
					
						
						costoMPaportada = renglones.get(kk).getCosto();
						
						//TODO: se guarda en la mp, el costo ingresado en el renglon de la tabla,
						//salvo sea 0. ?????????????
						//mp = materiaPrimaDao.setearCostoMP(mp, costoMPaportada);
						
					}

					trioMpCant.add(mp);
					trioMpCant.add(mpService.getCostoXUnidadString(mp, costoMPaportada));
					listaMpsNoIntervienen.add(trioMpCant);
				}
			}
			if(rdResultado == null)
				rdResultado = new RecuentoDatos();
			
			rdResultado.setCostoTotal(costoTotal);
			rdResultado.setCostoXKg(costoXKg);
			rdResultado.setCantidadAlimento(cantMpAlimento);
			rdResultado.setListaMP(listaMps);
			rdResultado.setListaMPNoINtervienen(listaMpsNoIntervienen);
			rdResultado.setListaComponenteVectorX(x);

			
			
	/*		if (imprimir) {
				
				return imprimirPlanillaFormula_actionPerformed();
			} else
				return null;
				*/
		}

	private Object imprimirPlanillaFormula_actionPerformed() {
		// TODO Auto-generated method stub
		return null;
	}

	private Vector procesarRequerimiento(ArrayList<Vector> restriccionesLista,
			Vector fo, Vector restriccionesMP, ArrayList<MpDTO> lista) throws Exception {
		Vector vector = null;
		try {
			armarMatriz(restriccionesLista, fo, restriccionesMP, 
					lista);
			//procesar3
			vector = procesar();
		} catch (Exception e) {
			throw e;
		}

		return vector;
	}

	/**
	 * Este metodo invoca la ejecucion del simplex en fortran a partir del
	 * archivo que acaba de generar. El resultado se muestra en pantalla.
	 */
	private Vector procesar() throws Exception {
		Vector vector;

		try {
			vector = ejecutar();
			return vector;

		} catch (Exception e) {
			String mensaje = "Ha ocurrido un error al ejecutar proceso. Comuniquse con su tecnico.";
			throw new ExceptionAplicacion(mensaje,
					Constantes.TipoException.ERROR);
		}

	}
	
	private static Vector ejecutar() throws Exception {

		Vector v = null;
		// verificar que existe el archivo de datos, y que no es vacio.
		// si hay algun problema, crear un archivo de datos ficticios.
		// que no se satisface con nada.
		// verificar que existe salida, sino crear archivo.
		Process process;
		try {
			String separador = File.separator;
			//TODO: sacar la dieccion de ejecucion del fortran en un properties
			String args = "c:" + separador + "TEMP" + separador;
			//String args = "d:" + separador + "temporal" + separador;
			
			String path = args + Constantes.PathArchivos.COSMINEXE;


			try {
				String auxiliar = null;
				Process p = Runtime.getRuntime().exec(
						"cmd /c "+path);
				InputStream is = p.getInputStream();
				BufferedReader br = new BufferedReader(
						new InputStreamReader(is));
//				while ((auxiliar = br.readLine()) != null)
//					System.out.println(auxiliar);
			} catch (Exception e) {
//				System.out.println("Error al Abrir el ejecutar");
			}

			Thread.sleep(1000);
			if (procesamiento == 1) {
				// se copia el archivo en salida1.txt para hacer el dual.

				copyfile(Constantes.PathArchivos.getDirectorioTemporal()
						+ Constantes.PathArchivos.SALIDA,
						Constantes.PathArchivos.getDirectorioTemporal()
								+ Constantes.PathArchivos.SALIDA2);
			}
			
			
			
			LeerArchivo l = new LeerArchivo();
//			System.out.println("va a leer archio en: "+Constantes.PathArchivos.getDirectorioTemporal()
//					+ Constantes.PathArchivos.SALIDA);
			l.leerArchivo(Constantes.PathArchivos.getDirectorioTemporal()
					+ Constantes.PathArchivos.SALIDA);
			FileInputStream in = new FileInputStream(
					Constantes.PathArchivos.getDirectorioTemporal()
							+ Constantes.PathArchivos.SALIDA);
			in.close();
			FileInputStream in2 = new FileInputStream(
					Constantes.PathArchivos.getDirectorioTemporal()
							+ Constantes.PathArchivos.FILEINSIMPLEX);
			in2.close();
			v = l.getVector();

			System.gc();
		} catch (IOException e3) {
			// TODO Auto-generated catch block
			e3.printStackTrace();
		} catch (Exception e) {
			System.out.println("error");
		}
		return v;

	}

	private static void copyfile(String srFile, String dtFile) {
		try {
			File f1 = new File(srFile);
			File f2 = new File(dtFile);
			InputStream in = new FileInputStream(f1);

			// For Append the file.
			// OutputStream out = new FileOutputStream(f2,true);

			// For Overwrite the file.
			OutputStream out = new FileOutputStream(f2);

			byte[] buf = new byte[1024];
			int len;
			while ((len = in.read(buf)) > 0) {
				out.write(buf, 0, len);
			}
			in.close();
			out.close();
//			System.out.println("File copied.");
		} catch (FileNotFoundException ex) {
//			System.out
//					.println(ex.getMessage() + " in the specified directory.");

		} catch (IOException e) {
//			System.out.println(e.getMessage());
		}
	}

	/**
	 * este metodo escribe la matriz en el archivo, luego de organizar las restricciones segun el orde
	 * que requiere el exec de cosmin.
	 * @param requerimientos
	 * @param fo
	 * @param restriccionesMP
	 * @param renglones
	 * @throws ExceptionAplicacion
	 */

	private void armarMatriz(ArrayList<Vector> requerimientos, Vector fo,
			Vector restriccionesMP, ArrayList<MpDTO> renglones) 

		 throws ExceptionAplicacion {
			// generar fo, generar matriz de mp,
			filaVariablesMpcodigo = null;
			m11 = 0;
			// m2 arranca en uno, por que la restriccion de energia esigual.
			m22 = 0;
			m33 = 0;
			Vector vectorMatrizSimplex = new Vector();
			Vector vectorMatrizIgual = new Vector();
			Vector vectorMatrizMayor = new Vector();
			Vector vectorMatrizMenor = new Vector();
			// se genera la FO
			// WriteArchivos.escribirLog("");
			// WriteArchivos.escribirLog("ahora armara la matriz de restricciones.");

			if (fo != null)
				vectorMatrizSimplex.add(fo);

			if (restriccionesMP != null) {
				for (int h = 0; h < restriccionesMP.size(); h++) {
					Vector v = (Vector) restriccionesMP.get(h);
					RestriccionSimple r1 = (RestriccionSimple) v.get(0);
					if (r1.esMayor() || r1.esMayorIgual()) {
						vectorMatrizMayor.add(v);
						masM2();
					} else if (r1.esMenor() || r1.esMenorIgual()) {

						vectorMatrizMenor.add(v);
						masM1();
					} else if (r1.esIgual()) {

						vectorMatrizIgual.add(v);
						masM3();
					}
				}
			}

			int row = renglones.size();
			String escribirLog = "";
			if (fo != null) {
				Iterator iteradorRequerimientos = requerimientos.iterator();
				while (iteradorRequerimientos.hasNext()) {

					Vector vComponente = (Vector) iteradorRequerimientos.next();
					// obtiene el componente
					Restriccion r = ((Restriccion) vComponente.get(0));

			

					if (r.esMayor() || r.esMayorIgual()) {
						vectorMatrizMayor.add(vComponente);
						masM2();
					} else if (r.esMenor() || r.esMenorIgual()) {
						vectorMatrizMenor.add(vComponente);
						masM1();
					} else if (r.esIgual()) {
						vectorMatrizIgual.add(vComponente);
						masM3();
					}

				
				}// while
			}// si hay fo

			for (int i = 0; i < vectorMatrizMenor.size(); i++) {
				vectorMatrizSimplex.add(vectorMatrizMenor.get(i));
			}
			for (int i = 0; i < vectorMatrizMayor.size(); i++) {
				vectorMatrizSimplex.add(vectorMatrizMayor.get(i));
			}
			for (int i = 0; i < vectorMatrizIgual.size(); i++) {
				vectorMatrizSimplex.add(vectorMatrizIgual.get(i));
			}

			
			try {
				deleteArchivos();
				String path = Constantes.PathArchivos.getDirectorioTemporal()
						+ Constantes.PathArchivos.FILEINSIMPLEX;
				mensaje = escribir(path, vectorMatrizSimplex, m11, m22, m33);
				if (mensaje != null)
					throw new Exception();// escribir(fo,energia,
				// matriz,restriccionesMP, m1, m2,m3,
				// mmax, nmax);
			} catch (Exception e) {
				throw new ExceptionAplicacion(mensaje,
						Constantes.TipoException.ERROR);
			}

		}


		private static void masM1() {
			m11++;
		}

		private static void masM2() {
			m22++;
		}

		private static void masM3() {
			m33++;
		}

	private Vector getRestriccionesMP(List<MpDTO> renglones, BigDecimal pv) {
		Vector vR = null;
		// String escribirLog = "";
		Vector vToneladaAlimento = null;
		// obtiene cada fila de restriccion de Mp.
		int rows = renglones.size();
		
		if (rows > 0) {
			// agregar la restriccion de que la cant de alimento de todas las mp
			// = 1000.
			vToneladaAlimento = new Vector(rows + 2);

			Igual igual = new Igual();
			BigDecimal cantAlimento = calcularCantAlimento();
			igual.setCantidad(cantAlimento);			
				
		//	igual.setCantidad(new Float(1));
			vToneladaAlimento.add(0, igual);

			// crea el vector de la fila de la matriz, con el lugar para agregar
			// el termino B.
			vR = new Vector(rows + 2);
			for (int i = 0; i < rows; i++) {
				MpDTO renglon = renglones.get(i);	
				
					Vector v = null;					
					BigDecimal	cantidad =renglon.getIguala();						
					
					if (cantidad.compareTo(BigDecimal.ZERO) > 0) {
						v = getVectorRestriccion(rows, cantidad, i,
								Constantes.EncabezadosRecontar.IGUALA_INT);
						vR.add(v);
					}
					
					
					
				     cantidad = renglon.getMasde();
					if (cantidad.compareTo(BigDecimal.ZERO) > 0) {
						v = getVectorRestriccion(rows, cantidad, i,
								Constantes.EncabezadosRecontar.MASDE_INT);
						vR.add(v);
					}
					
					
					
						cantidad = renglon.getMenosde();
	
					if (cantidad.compareTo(BigDecimal.ZERO) > 0) {
						v = getVectorRestriccion(rows, cantidad, i,
								Constantes.EncabezadosRecontar.MENOSDE_INT);
						vR.add(v);
					}

				 vToneladaAlimento.add("1");
				
//				}
			}

			vR.add(vToneladaAlimento);
			

		}
		return vR;
	}

	private BigDecimal calcularCantAlimento() {
		// TODO por ahora es solo el cms calculdo para la nrc
		return getCms();
	}

	private RestriccionSimple getCantidadMpMayorIgual(BigDecimal pv, BigDecimal porcentaje) {
		MayorIgual rest = new MayorIgual();		
		
		//TODO: ver la cantidad?
		BigDecimal cantAlimento =  pv.multiply (porcentaje).divide(ONEHUNDERT);		
		
		rest.setCantidad(cantAlimento);	
		return rest;
	}

	private RestriccionSimple getCantidadMpMenorIgual(BigDecimal pv, BigDecimal porcentaje) {
		MenorIgual rest = new MenorIgual();		
		
		//TODO: ver la cantidad?
		BigDecimal cantAlimento =  pv.multiply (porcentaje).divide(ONEHUNDERT);		
		
		rest.setCantidad(cantAlimento);	
		return rest;
	}

	
	private Vector getVectorRestriccion(int rows, BigDecimal cantidad, int i,
			int tipoRestr) {
		RestriccionSimple r = null;

		switch (tipoRestr) {
		case 1:
			r = new Igual();
			break;
		case 2:
			r = new MayorIgual();
			break;
		case 3:
			r = new MenorIgual();
			break;

		}

		Vector v = new Vector();
		for (int j = 0; j < i; j++)
			v.add(j, "0");
		v.add(i, "1");
		for (int x = i + 1; x < rows; x++)
			v.add(x, "0");

		BigDecimal ff = cantidad.divide(new BigDecimal(100), Constantes.presicion, Constantes.redondeomode);
		r.setCantidad(ff);
		v.add(0, r);
		return v;
	}

	private Vector generarFo(List<MpDTO> renglones) {
		// recorrer las matrices de la tabla de restricciones.
		// obtener los id de materia prima y su costo.
		Vector vFO = null;
		int rows = renglones.size();
		String texto = "";
		if (rows > 0) {
			vFO = new Vector();

			for (int i = 0; i < rows; i++) {
				
				MateriaPrima mp = null;
				try {
					mp = renglones.get(i).getMp();
				} catch (Exception e) {
				
					//TODO: logger.error("",e);
				}
				ItemFO item = new ItemFO();
				item.setMpFO(mp);
				item.setCosto(renglones.get(i).getCantidad());
				vFO.add(item);
				
				texto = texto + mp.getCosto() + " (X" + i + ") + ";
			}
		}

		Igual i = new Igual();
		i.setCantidad(BigDecimal.ZERO);
		vFO.add(0, i);

		return vFO;
	}

	/**
	 * 
	 * @param idanimal
	 * @param renglones
	 * @param listaRestriccionesModificadas 
	 *  @return
	 */
	private ArrayList getMatriz(ArrayList<MpDTO> renglones) {
	
		ArrayList lrestricciones = new ArrayList();
		try{

		
		//Obtengo la lista de requerimientos del animal seleccionado desde la base, lo clono		
		Iterator iter = listaRequerimientosParaFormular.iterator();

		Iterator materiasprimas;
		int row = renglones.size();
		Vector vComponenteMenor = null;
		Vector vComponenteMayor = null;	
		
		BigDecimal fcero = BigDecimal.ZERO;		
		
		while (iter.hasNext()) {
			Restriccion r = (Restriccion) iter.next();
//TODO: se supone que son todas esF en este caso.	??		
//			if (((Restriccion) r).isEsF()) {
				if (r.esRango()) {
					// obtiene el componente
					Componente c = ((RestriccionRango) r).getComponenteById();
					
					if(componenteService.esProteinaBruta(c))
					{
					
					//obtiene la restriccion para la roteína bruta
				
						if (((RestriccionRango) r).getValorMax() != null) {
							if (((RestriccionRango) r).getValorMax()
									.floatValue() < 100) {
								//genera restricciones simples a partir de la de rango. 
								vComponenteMenor = new Vector();
								
								BigDecimal cantidad = getCms().multiply(((RestriccionRango) r).getValorMax());
								vComponenteMenor
										.add(0,
												reqService
														.getRestriccionMenor((RestriccionRango) r, cantidad));
							}
						}

						if (((RestriccionRango) r).getValorMin() != null) {
							vComponenteMayor = new Vector();
							
							BigDecimal cantidad = getCms().multiply(((RestriccionRango) r).getValorMin());
							
							vComponenteMayor.add(0, reqService
									.getRestriccionMayor((RestriccionRango) r, cantidad));
						}

						for (int i = 0; i < row; i++) {
							// obtener su composicion.
							// Buscar el aporte del componente
							
							MateriaPrima mp = null;
							try {
								mp = renglones.get(i).getMp();
							} catch (Exception e) {
								// TODO Auto-generated catch block
								//logger.error("",e);
							}
							ComponenteValor cv = (ComponenteValor) mpService
									.getComponenteFromComposicion(mp, c);

							// obtiene el aporte del componente a la MP
							BigDecimal cantAporte = cv.getCantidad();

							// guarda el valor en el vector.
							if (vComponenteMenor != null)
								vComponenteMenor.add(cantAporte);
							if (vComponenteMayor != null)
								vComponenteMayor.add(cantAporte);
						}
						int i = 0;
						if (vComponenteMayor != null) {
							lrestricciones.add(vComponenteMayor);
							String texto = "";
							for (int hh = 1; hh < vComponenteMayor.size(); hh++) {
								texto = texto
										+ " "
										+ ((BigDecimal) vComponenteMayor.get(hh))
												.toString() + " (X" + i
										+ ") + ";
								;
								i++;
							}
							// WriteArchivos.escribirLog(texto
							System.out.println( texto +" >= "
							 + ((MayorIgual) vComponenteMayor.get(0))
							 .getCantidad());
						}
						i = 0;
						if (vComponenteMenor != null) {
							lrestricciones.add(vComponenteMenor);
							String texto = "";
							for (int hh = 1; hh < vComponenteMenor.size(); hh++) {
								texto = texto
										+ " "
										+ ((BigDecimal) vComponenteMenor.get(hh))
												.toString() + " (X" + i
										+ ") + ";
								;
								i++;
							}
							// WriteArchivos.escribirLog(
							System.out.println(texto + " <= "  + ((MenorIgual) vComponenteMenor.get(0))
									 .getCantidad());
						}
					}//si es proteina
					
					else{
						if(componenteService.esFDNForraje(c))
						{
							//obtiene la restriccion para el FDN de las mp que son forraje
							
							if (((RestriccionRango) r).getValorMax() != null) {
								if (((RestriccionRango) r).getValorMax()
										.floatValue() < 100) {
									//genera restricciones simples a partir de la de rango. 
									vComponenteMenor = new Vector();
									
									BigDecimal cantidad = getCms().multiply(((RestriccionRango) r).getValorMax());
									vComponenteMenor
											.add(0,
													reqService
															.getRestriccionMenor((RestriccionRango) r, cantidad));
								}
							}

							if (((RestriccionRango) r).getValorMin() != null) {
								vComponenteMayor = new Vector();
								
								BigDecimal cantidad = getCms().multiply(((RestriccionRango) r).getValorMin());
								
								vComponenteMayor.add(0, reqService
										.getRestriccionMayor((RestriccionRango) r, cantidad));
							}

							for (int i = 0; i < row; i++) {
								// obtener su composicion.
								// Buscar el aporte del componente
								
								MateriaPrima mp = null;
								try {
									mp = renglones.get(i).getMp();
								} catch (Exception e) {
									// TODO Auto-generated catch block
									//logger.error("",e);
								}
								
								BigDecimal cantAporte = BigDecimal.ZERO;
								
								if(mp.getTipoEnergia().esForraje())
								{
									ComponenteValor cv = (ComponenteValor) mpService
											.getComponenteFromComposicion(mp, c);
	
									// obtiene el aporte del componente a la MP							
									cantAporte = cv.getCantidad();
								}
									
									// guarda el valor en el vector.
									if (vComponenteMenor != null)
										vComponenteMenor.add(cantAporte);
									if (vComponenteMayor != null)
										vComponenteMayor.add(cantAporte);
								
							}
							int i = 0;
							if (vComponenteMayor != null) {
								lrestricciones.add(vComponenteMayor);
								String texto = "";
								for (int hh = 1; hh < vComponenteMayor.size(); hh++) {
									texto = texto
											+ " "
											+ ((BigDecimal) vComponenteMayor.get(hh))
													.toString() + " (X" + i
											+ ") + ";
									;
									i++;
								}
								System.out.println(texto
								 + " >= "
								 + ((MayorIgual) vComponenteMayor.get(0))
								 .getCantidad());
							}
							i = 0;
							if (vComponenteMenor != null) {
								lrestricciones.add(vComponenteMenor);
								String texto = "";
								for (int hh = 1; hh < vComponenteMenor.size(); hh++) {
									texto = texto
											+ " "
											+ ((BigDecimal) vComponenteMenor.get(hh))
													.toString() + " (X" + i
											+ ") + ";
									;
									i++;
								}
								System.out.println(texto
										 + " <= "
										 + ((MenorIgual) vComponenteMenor.get(0))
										 .getCantidad());
							}
						}//si es FDNForraje
						
						else{
							if(componenteService.esFDN(c))
							{
								
								if (((RestriccionRango) r).getValorMax() != null) {
									if (((RestriccionRango) r).getValorMax()
											.floatValue() < 100) {
										//genera restricciones simples a partir de la de rango. 
										vComponenteMenor = new Vector();
										
										BigDecimal cantidad = getCms().multiply(((RestriccionRango) r).getValorMax());
										vComponenteMenor
												.add(0,
														reqService
																.getRestriccionMenor((RestriccionRango) r, cantidad));
									}
								}

								if (((RestriccionRango) r).getValorMin() != null) {
									vComponenteMayor = new Vector();
									
									BigDecimal cantidad = getCms().multiply(((RestriccionRango) r).getValorMin());
									
									vComponenteMayor.add(0, reqService
											.getRestriccionMayor((RestriccionRango) r, cantidad));
								}

								for (int i = 0; i < row; i++) {
									// obtener su composicion.
									// Buscar el aporte del componente
									
									BigDecimal cantAporte = BigDecimal.ZERO;
									
									//calcula el fdn para cada mp
									cantAporte = procesarService.getFdn(renglones.get(i));
										
										// guarda el valor en el vector.
										if (vComponenteMenor != null)
											vComponenteMenor.add(cantAporte);
										if (vComponenteMayor != null)
											vComponenteMayor.add(cantAporte);
									
								}
								int i = 0;
								if (vComponenteMayor != null) {
									lrestricciones.add(vComponenteMayor);
									String texto = "";
									for (int hh = 1; hh < vComponenteMayor.size(); hh++) {
										texto = texto
												+ " "
												+ ((BigDecimal) vComponenteMayor.get(hh))
														.toString() + " (X" + i
												+ ") + ";
										;
										i++;
									}
									System.out.println(texto
									 + " >= "
									 + ((MayorIgual) vComponenteMayor.get(0))
									 .getCantidad());
								}
								i = 0;
								if (vComponenteMenor != null) {
									lrestricciones.add(vComponenteMenor);
									String texto = "";
									for (int hh = 1; hh < vComponenteMenor.size(); hh++) {
										texto = texto
												+ " "
												+ ((BigDecimal) vComponenteMenor.get(hh))
														.toString() + " (X" + i
												+ ") + ";
										;
										i++;
									}
									System.out.println(texto
											 + " <= "
											 + ((MenorIgual) vComponenteMenor.get(0))
											 .getCantidad());
								
								
								}
							}//SI ES fdn
							else{
								//NFC (carbohidratos no fibrosos)
								
								if(componenteService.esNFCDigest(c)){
									if (((RestriccionRango) r).getValorMax() != null) {
										if (((RestriccionRango) r).getValorMax()
												.floatValue() < 100) {
											//genera restricciones simples a partir de la de rango. 
											vComponenteMenor = new Vector();
											
											BigDecimal cantidad = getCms().multiply(((RestriccionRango) r).getValorMax());
											vComponenteMenor
													.add(0,
															reqService
																	.getRestriccionMenor((RestriccionRango) r, cantidad));
										}
									}

									if (((RestriccionRango) r).getValorMin() != null) {
										vComponenteMayor = new Vector();
										
										BigDecimal cantidad = getCms().multiply(((RestriccionRango) r).getValorMin());
										
										vComponenteMayor.add(0, reqService
												.getRestriccionMayor((RestriccionRango) r, cantidad));
									}

									for (int i = 0; i < row; i++) {
										// obtener su composicion.
										// Buscar el aporte del componente
										
										MateriaPrima mp = null;
										try {
											mp = renglones.get(i).getMp();
										} catch (Exception e) {
											// TODO Auto-generated catch block
											//logger.error("",e);
										}
										ComponenteValor cv = (ComponenteValor) mpService
												.getComponenteFromComposicion(mp, c);

										// obtiene el aporte del componente a la MP
										BigDecimal cantAporte = cv.getCantidad();

										// guarda el valor en el vector.
										if (vComponenteMenor != null)
											vComponenteMenor.add(cantAporte);
										if (vComponenteMayor != null)
											vComponenteMayor.add(cantAporte);
									}
									int i = 0;
									if (vComponenteMayor != null) {
										lrestricciones.add(vComponenteMayor);
										String texto = "";
										for (int hh = 1; hh < vComponenteMayor.size(); hh++) {
											texto = texto
													+ " "
													+ ((BigDecimal) vComponenteMayor.get(hh))
															.toString() + " (X" + i
													+ ") + ";
											;
											i++;
										}
										System.out.println(texto
										 + " >= "
										 + ((MayorIgual) vComponenteMayor.get(0))
										 .getCantidad());
									}
									i = 0;
									if (vComponenteMenor != null) {
										lrestricciones.add(vComponenteMenor);
										String texto = "";
										for (int hh = 1; hh < vComponenteMenor.size(); hh++) {
											texto = texto
													+ " "
													+ ((BigDecimal) vComponenteMenor.get(hh))
															.toString() + " (X" + i
													+ ") + ";
											;
											i++;
										}
										System.out.println(texto
												 + " <= "
												 + ((MenorIgual) vComponenteMenor.get(0))
												 .getCantidad());
									
									
									}
									
								}else{
									//RDP (Proteina degrad. Ruminal)
									//ver como sacamos esto para cada mp
									if(componenteService.esRDP(c)){
										if (((RestriccionRango) r).getValorMax() != null) {
											if (((RestriccionRango) r).getValorMax()
													.floatValue() < 100) {
												//genera restricciones simples a partir de la de rango. 
												vComponenteMenor = new Vector();
												
												BigDecimal cantidad = getCms().multiply(((RestriccionRango) r).getValorMax());
												vComponenteMenor
														.add(0,
																reqService
																		.getRestriccionMenor((RestriccionRango) r, cantidad));
											}
										}

										if (((RestriccionRango) r).getValorMin() != null) {
											vComponenteMayor = new Vector();
											
											BigDecimal cantidad = getCms().multiply(((RestriccionRango) r).getValorMin());
											
											vComponenteMayor.add(0, reqService
													.getRestriccionMayor((RestriccionRango) r, cantidad));
										}

										for (int i = 0; i < row; i++) {
											// obtener su composicion.
											// Buscar el aporte del componente
											
											MateriaPrima mp = null;
											try {
												mp = renglones.get(i).getMp();
											} catch (Exception e) {
												// TODO Auto-generated catch block
												//logger.error("",e);
											}
											ComponenteValor cv = (ComponenteValor) mpService
													.getComponenteFromComposicion(mp, c);

											// obtiene el aporte del componente a la MP
											BigDecimal cantAporte = cv.getCantidad();

											// guarda el valor en el vector.
											if (vComponenteMenor != null)
												vComponenteMenor.add(cantAporte);
											if (vComponenteMayor != null)
												vComponenteMayor.add(cantAporte);
										}
										int i = 0;
										if (vComponenteMayor != null) {
											lrestricciones.add(vComponenteMayor);
											String texto = "";
											for (int hh = 1; hh < vComponenteMayor.size(); hh++) {
												texto = texto
														+ " "
														+ ((BigDecimal) vComponenteMayor.get(hh))
																.toString() + " (X" + i
														+ ") + ";
												;
												i++;
											}
											System.out.println(texto
											 + " >= "
											 + ((MayorIgual) vComponenteMayor.get(0))
											 .getCantidad());
										}
										i = 0;
										if (vComponenteMenor != null) {
											lrestricciones.add(vComponenteMenor);
											String texto = "";
											for (int hh = 1; hh < vComponenteMenor.size(); hh++) {
												texto = texto
														+ " "
														+ ((BigDecimal) vComponenteMenor.get(hh))
																.toString() + " (X" + i
														+ ") + ";
												;
												i++;
											}
											System.out.println(texto
													 + " <= "
													 + ((MenorIgual) vComponenteMenor.get(0))
													 .getCantidad());
										
										
										}
									}else{
										
										//RUP (proteína pasante o by pass)
										//ver como sacamos esto para cada mp

										if(componenteService.esRUP(c)){
											if (((RestriccionRango) r).getValorMax() != null) {
												if (((RestriccionRango) r).getValorMax()
														.floatValue() < 100) {
													//genera restricciones simples a partir de la de rango. 
													vComponenteMenor = new Vector();
													
													BigDecimal cantidad = getCms().multiply(((RestriccionRango) r).getValorMax());
													vComponenteMenor
															.add(0,
																	reqService
																			.getRestriccionMenor((RestriccionRango) r, cantidad));
												}
											}

											if (((RestriccionRango) r).getValorMin() != null) {
												vComponenteMayor = new Vector();
												
												BigDecimal cantidad = getCms().multiply(((RestriccionRango) r).getValorMin());
												
												vComponenteMayor.add(0, reqService
														.getRestriccionMayor((RestriccionRango) r, cantidad));
											}

											for (int i = 0; i < row; i++) {
												// obtener su composicion.
												// Buscar el aporte del componente
												
												MateriaPrima mp = null;
												try {
													mp = renglones.get(i).getMp();
												} catch (Exception e) {
													// TODO Auto-generated catch block
													//logger.error("",e);
												}
												ComponenteValor cv = (ComponenteValor) mpService
														.getComponenteFromComposicion(mp, c);

												// obtiene el aporte del componente a la MP
												BigDecimal cantAporte = cv.getCantidad();

												// guarda el valor en el vector.
												if (vComponenteMenor != null)
													vComponenteMenor.add(cantAporte);
												if (vComponenteMayor != null)
													vComponenteMayor.add(cantAporte);
											}
											int i = 0;
											if (vComponenteMayor != null) {
												lrestricciones.add(vComponenteMayor);
												String texto = "";
												for (int hh = 1; hh < vComponenteMayor.size(); hh++) {
													texto = texto
															+ " "
															+ ((BigDecimal) vComponenteMayor.get(hh))
																	.toString() + " (X" + i
															+ ") + ";
													;
													i++;
												}
												System.out
														.println(texto
												 + " >= "
												 + ((MayorIgual) vComponenteMayor.get(0))
												 .getCantidad());
											}
											i = 0;
											if (vComponenteMenor != null) {
												lrestricciones.add(vComponenteMenor);
												String texto = "";
												for (int hh = 1; hh < vComponenteMenor.size(); hh++) {
													texto = texto
															+ " "
															+ ((BigDecimal) vComponenteMenor.get(hh))
																	.toString() + " (X" + i
															+ ") + ";
													;
													i++;
												}
												System.out.println(texto
														 + " <= "
														 + ((MenorIgual) vComponenteMenor.get(0))
														 .getCantidad());
											
											
											}
											
										}else{
											
											//Grasa
											if(componenteService.esGrasa(c)){
												//ver como sacamos esto
												if (((RestriccionRango) r).getValorMax() != null) {
													if (((RestriccionRango) r).getValorMax()
															.floatValue() < 100) {
														//genera restricciones simples a partir de la de rango. 
														vComponenteMenor = new Vector();
														
														BigDecimal cantidad = getCms().multiply(((RestriccionRango) r).getValorMax());
														vComponenteMenor
																.add(0,
																		reqService
																				.getRestriccionMenor((RestriccionRango) r, cantidad));
													}
												}

												if (((RestriccionRango) r).getValorMin() != null) {
													vComponenteMayor = new Vector();
													
													BigDecimal cantidad = getCms().multiply(((RestriccionRango) r).getValorMin());
													
													vComponenteMayor.add(0, reqService
															.getRestriccionMayor((RestriccionRango) r, cantidad));
												}

												for (int i = 0; i < row; i++) {
													// obtener su composicion.
													// Buscar el aporte del componente
													
													MateriaPrima mp = null;
													try {
														mp = renglones.get(i).getMp();
													} catch (Exception e) {
														// TODO Auto-generated catch block
														//logger.error("",e);
													}
													ComponenteValor cv = (ComponenteValor) mpService
															.getComponenteFromComposicion(mp, c);

													// obtiene el aporte del componente a la MP
													BigDecimal cantAporte = cv.getCantidad();

													// guarda el valor en el vector.
													if (vComponenteMenor != null)
														vComponenteMenor.add(cantAporte);
													if (vComponenteMayor != null)
														vComponenteMayor.add(cantAporte);
												}
												int i = 0;
												if (vComponenteMayor != null) {
													lrestricciones.add(vComponenteMayor);
													String texto = "";
													for (int hh = 1; hh < vComponenteMayor.size(); hh++) {
														texto = texto
																+ " "
																+ ((BigDecimal) vComponenteMayor.get(hh))
																		.toString() + " (X" + i
																+ ") + ";
														;
														i++;
													}
													System.out
															.println(texto
													 + " >= "
													 + ((MayorIgual) vComponenteMayor.get(0))
													 .getCantidad());
												}
												i = 0;
												if (vComponenteMenor != null) {
													lrestricciones.add(vComponenteMenor);
													String texto = "";
													for (int hh = 1; hh < vComponenteMenor.size(); hh++) {
														texto = texto
																+ " "
																+ ((BigDecimal) vComponenteMenor.get(hh))
																		.toString() + " (X" + i
																+ ") + ";
														;
														i++;
													}
													System.out.println(texto
															 + " <= "
															 + ((MenorIgual) vComponenteMenor.get(0))
															 .getCantidad());
												
												
												}
											}else{
												
												
												
											}
											
										}
									}
								}
							}
					
							
						}
					}
					
				} //fin if es rango()
				else {

					if (r.esDoble()) {
						
						
						
						Componente c = ((RestriccionDoble) r)
								.getComponenteById1();
						Componente c2 = ((RestriccionDoble) r)
								.getComponenteById2();

						
									
										MenorIgual menor = reqService
												.getRestriccionMenor((RestriccionDoble) r);
										MayorIgual mayor = reqService
												.getRestriccionMayor((RestriccionDoble) r);
										// WriteArchivos.escribirLog(r.getRestriccionToString()+
										// ": cantid del componente de la mp - ((cant energia de la mp/1000) * cantidad a cumplir)");

										if (menor != null) {
											if (menor.getCantidad()
													.floatValue() < 100) {
												vComponenteMenor = new Vector();
											}
										}
										if (mayor != null) {
											vComponenteMayor = new Vector();
										}

										for (int i = 0; i < row; i++) {
											//TODO: ACA NO HAY ENERGIAAAAAAA
											ComponenteValor cvenergiaMP;
											// obtener su composicion.
											// Buscar el aporte del componente
											
											MateriaPrima mp = null;
											try {
												mp = renglones.get(i).getMp();
											} catch (Exception e) {
							
												//logger.error("",e);
											}

											ComponenteValor cv = mpService
													.getComponenteFromComposicion(
															mp, c);
											cvenergiaMP = mpService
													.getComponenteFromComposicion(
															mp,
															null); // animal.getCvenergia());
											// obtiene el aporte del componente
											// a la MP
											BigDecimal cantAporte1 = calcularCantidadAporte(cv );
											
											BigDecimal cantAporteenergia = calcularCantidadAporte(cvenergiaMP );

											
											if (vComponenteMayor != null) {
												float vMayor = cantAporte1
														.floatValue()
														- ((cantAporteenergia
																.floatValue() * mayor
																.getCantidad()
																.floatValue()) / 1000);
												Float vMayorFloat = new Float(
														vMayor);
												// guarda el valor en el vector.
												vComponenteMayor
														.add(vMayorFloat);
											}

											if (vComponenteMenor != null) {
												float vMenor = cantAporte1
														.floatValue()
														- ((cantAporteenergia
																.floatValue() * menor
																.getCantidad()
																.floatValue()) / 1000);
												Float vMenorFloat = new Float(
														vMenor);
												vComponenteMenor
														.add(vMenorFloat);
											}
										}
										int i = 0;
										if (vComponenteMenor != null) {
											menor.setCantidad(fcero);
											menor.setComponente(c2);
											vComponenteMenor.add(0, menor);
											lrestricciones
													.add(vComponenteMenor);
											String texto = "";
											for (int hh = 1; hh < vComponenteMenor
													.size(); hh++) {
												texto = texto
														+ " "
														+ ((Float) vComponenteMenor
																.get(hh))
																.toString()
														+ " (X" + i + ") + ";
												i++;
											}
											System.out.println(texto + " <= 0");
										}
										i = 0;
										if (vComponenteMayor != null) {
											mayor.setCantidad(fcero);
											mayor.setComponente(c2);
											vComponenteMayor.add(0, mayor);
											lrestricciones
													.add(vComponenteMayor);
											String texto = "";
											for (int hh = 1; hh < vComponenteMayor
													.size(); hh++) {
												texto = texto
														+ " "
														+ ((Float) vComponenteMayor
																.get(hh))
																.toString()
														+ " (X" + i + ") + ";
												i++;
											}
										System.out.println(texto + " >= 0");
										}

					}// si es doble
					else {
						// si es FA
						if (r.esFA()) {
							Componente c = ((RestriccionFactorAjuste) r)
									.getComponente();
							vComponenteMayor = new Vector();
							// WriteArchivos.escribirLog("");
							// WriteArchivos.escribirLog(c.getDescripcion()
							// + ", requiere "
							// + ((RestriccionFactorAjuste) r)
							// .getCantidad() + " cada mil.");
							// WriteArchivos
							// .escribirLog("cant componente de la mp - ((energia de la mp * cantidad requerida)/1000)");

							MayorIgual mayor = new MayorIgual();

							mayor.setComponente(c);
							mayor.setCantidad(fcero);

							vComponenteMayor.add(0, mayor);

							for (int i = 0; i < row; i++) {
								//TODO: ACA NO HAY ENERGIAAAAAAA
								ComponenteValor cvenergiaMP;
								// obtener su composicion.
								// Buscar el aporte del componente
								
								MateriaPrima mp = null;
								try {
									mp = renglones.get(i).getMp();
								} catch (Exception e) {
									// TODO Auto-generated catch block
									//logger.error("",e);
								}
								ComponenteValor cv = mpService
										.getComponenteFromComposicion(mp, c);
								cvenergiaMP = mpService
										.getComponenteFromComposicion(mp,null); //null); // animal.getCvenergia());
								// obtiene el aporte del componente a la MP
								
								BigDecimal cantAporte = calcularCantidadAporte(cv );
								BigDecimal cantAporteenergia = calcularCantidadAporte(cvenergiaMP );
								
									
								float vMayor = cantAporte.floatValue()
										- (cantAporteenergia
												.floatValue()
												* (((RestriccionFactorAjuste) r)
														.getCantidad()
														.floatValue()) / 1000);
								Float vMayorFloat = new Float(vMayor);
								// guarda el valor en el vector.

								vComponenteMayor.add(vMayorFloat);
								// WriteArchivos.escribirLog("mp:
								// "+mp.getDescripcion()+" aporta
								// "+cv.getCantidad());
								// WriteArchivos.escribirLog("=
								// "+cantAporte.floatValue()+" -
								// ("+cvenergiaMP.getCantidad().floatValue()+" *
								// "+((RestriccionFactorAjuste)r).getCantidad().floatValue()+"/1000)
								// = "+ vMayor);

							}
							int i = 0;
							if (vComponenteMayor != null) {
								String texto = "";
								for (int hh = 1; hh < vComponenteMayor.size(); hh++) {
									texto = texto
											+ " "
											+ ((Float) vComponenteMayor.get(hh))
													.toString() + " (X" + i
											+ ") + ";
									i++;
								}
								System.out.println(texto + " >= 0");
							}
							lrestricciones.add(vComponenteMayor);

						} else {
							if (r.esSimple()) {

								Componente c = ((RestriccionSimple) r)
										.getComponenteById();
								
								// hace las restricciones para todos los componentes
					
								
							if (r.esMayor() || r.esMayorIgual()) {

								vComponenteMayor = new Vector();
								// WriteArchivos.escribirLog("");
								// WriteArchivos.escribirLog(c.getDescripcion()
								// + ", requiere "
								// + ((RestriccionSimple) r).getCantidad()
								// + " cada mil.");
								// WriteArchivos
								// .escribirLog("cant componente de la mp");

								MayorIgual mayor = new MayorIgual();

								mayor.setComponente(c);
								mayor.setCantidad(((RestriccionSimple) r)
										.getCantidad());

								vComponenteMayor.add(0, mayor);

								for (int i = 0; i < row; i++) {

									// obtener su composicion.
									// Buscar el aporte del componente
									
									MateriaPrima mp = null;
									try {
										mp = renglones.get(i).getMp();
									} catch (Exception e) {
										// TODO Auto-generated catch block
										//logger.error("",e);
									}
									ComponenteValor cv = mpService
											.getComponenteFromComposicion(mp, c);

									// obtiene el aporte del componente a la MP
									BigDecimal cantAporte = calcularCantidadAporte(cv );//cv.getCantidad();

									float vMayor = cantAporte.floatValue();
									Float vMayorFloat = new Float(vMayor);
									// guarda el valor en el vector.

									vComponenteMayor.add(vMayorFloat);

								}
								int i = 0;
								if (vComponenteMayor != null) {
									String texto = "";
									for (int hh = 1; hh < vComponenteMayor
											.size(); hh++) {
										texto = texto
												+ " "
												+ ((Float) vComponenteMayor
														.get(hh)).toString()
												+ " (X" + i + ") + ";
										i++;
									}
									System.out.println(texto
											+ " >= "
											+ ((RestriccionSimple) r)
													.getCantidad().toString());
								}
								lrestricciones.add(vComponenteMayor);						
									
									
								} else {
									if (r.esMenor() || r.esMenorIgual()) {

										vComponenteMenor = new Vector();
										
										MenorIgual menor = new MenorIgual();

										menor.setComponente(c);
										menor.setCantidad(((RestriccionSimple) r)
												.getCantidad());

										vComponenteMenor.add(0, menor);

										for (int i = 0; i < row; i++) {

											// obtener su composicion.
											// Buscar el aporte del componente
											
											MateriaPrima mp = null;
											try {
												mp = renglones.get(i).getMp();
											} catch (Exception e) {
												// TODO Auto-generated catch block
												//logger.error("",e);
											}
											ComponenteValor cv = mpService
													.getComponenteFromComposicion(mp, c);

											// obtiene el aporte del componente a la MP
											BigDecimal cantAporte = calcularCantidadAporte(cv );// cv.getCantidad();

											BigDecimal vMenor = cantAporte;
											BigDecimal vMenorFloat =vMenor;
											// guarda el valor en el vector.

											vComponenteMenor.add(vMenorFloat);

										}
										int i = 0;
										if (vComponenteMenor != null) {
											String texto = "";
											for (int hh = 1; hh < vComponenteMenor
													.size(); hh++) {
												texto = texto
														+ " "
														+ ((Float) vComponenteMenor
																.get(hh)).toString()
														+ " (X" + i + ") + ";
												i++;
											}
											System.out.println(texto
													+ " >= "
													+ ((RestriccionSimple) r)
															.getCantidad().toString());
										}
										lrestricciones.add(vComponenteMenor);	
									} else {
										if (r.esIgual()) {
											
											vComponenteMenor = new Vector();
											
											Igual igual = new Igual();

											igual.setComponente(c);
											igual.setCantidad(((RestriccionSimple) r)
													.getCantidad());

											vComponenteMenor.add(0, igual);

											for (int i = 0; i < row; i++) {

												// obtener su composicion.
												// Buscar el aporte del componente
											
												MateriaPrima mp = null;
												try {
													mp = renglones.get(i).getMp();
												} catch (Exception e) {
													// TODO Auto-generated catch block
													////logger.error("",e);
												}
												ComponenteValor cv = mpService
														.getComponenteFromComposicion(mp, c);

												// obtiene el aporte del componente a la MP
												BigDecimal cantAporte = calcularCantidadAporte(cv );//cv.getCantidad();

												float vMenor = cantAporte.floatValue();
												Float vMenorFloat = new Float(vMenor);
												// guarda el valor en el vector.

												vComponenteMenor.add(vMenorFloat);

											}
											int i = 0;
											if (vComponenteMenor != null) {
												String texto = "";
												for (int hh = 1; hh < vComponenteMenor
														.size(); hh++) {
													texto = texto
															+ " "
															+ ((Float) vComponenteMenor
																	.get(hh)).toString()
															+ " (X" + i + ") + ";
													i++;
												}
												System.out.println(texto
														+ " >= "
														+ ((RestriccionSimple) r)
																.getCantidad().toString());
											}
											lrestricciones.add(vComponenteMenor);

										}
									}
								}
							} //else es simple
						}
					}// else
				}// else
				vComponenteMenor = null;
				vComponenteMayor = null;
           //TODO: se supone que todas son esf
		//}// si es f.
		}

		
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return lrestricciones;
	}


	

	private static void resetProcesamiento() {
		procesamiento = 1;
	}

	private static void aumentarProcesamiento() {
		procesamiento++;
	}
	
	private BigDecimal calcularCantidadAporte(ComponenteValor componente) {
		return componente.getCantidad();
		
	
	}
	
	private void deleteArchivos() {
		String path = Constantes.PathArchivos.getDirectorioTemporal()
				+ Constantes.PathArchivos.FILEINSIMPLEX;
		borrar(path);
		path = Constantes.PathArchivos.getDirectorioTemporal()
				+ Constantes.PathArchivos.SALIDA;
		borrar(path);

	}
	

	public boolean borrar(String path) {
		boolean bool = false;
		File f = new File(path);
		System.gc();
		if (f.exists()) {
			if (f.delete()) {
				bool = true;
//				System.out.println(path + " Borrado con exito :)");
			} else {
				FileInputStream in;

				try {
					in = new FileInputStream(path);
					in.close();
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					System.out.println("error");
				} catch (IOException e) {
					// TODO Auto-generated catch block
					System.out.println("error");
				}
				if (f.delete()) {
					bool = true;
//					System.out.println(path + " Borrado con exito :)");
				} else {
					bool = false;
					System.out
							.println("Se ocaciono un error al borrar el directorio :(");
				}
			}
		} else {
			bool = false;
//			System.out.println(path + " El directorio no existe :(");
		}
		return bool;
	}
	
	private String escribir(String path, Vector vectorMatrizSimplex, int m1,
			int m2, int m3) {

		int m = m1 + m2 + m3;
		Vector f1 = (Vector) vectorMatrizSimplex.elementAt(1);
		int n = f1.size() - 1;
		String linea1 = "" + n + " " + m + " " + m1 + " " + m2 + " " + m3;
		int filas = ((m + 1) * (n + 1) + 1);
		String[] lineas = new String[filas];

		int fila = 0;
		try {

			lineas[fila] = linea1;
			fila++;
//			System.out.println(linea1);
			for (int i = 0; i < vectorMatrizSimplex.size(); i++) {
				String texto = new String("");
				Vector fi = (Vector) vectorMatrizSimplex.elementAt(i);
				RestriccionSimple r = (RestriccionSimple) fi.get(0);
				BigDecimal valor = r.getCantidad();
				texto = valor.toString();
				// escribir(texto);
				// lineas.append(texto+";");
				lineas[fila] = texto;
				fila++;
				// WriteArchivos.escribirLog(r.getComponenteById().getDescripcion());
				Componente compon = r.getComponenteById();
//				if (compon != null)
////					System.out.println(compon.getDescripcion());
//				else
////					System.out.println();
				// WriteArchivos.escribirLog(texto);
//				System.out.println(texto);
				for (int j = 1; j < fi.size(); j++) {
					try {
						Float t = new Float(fi.elementAt(j).toString());

						texto = t.toString();

					} catch (Exception e) {
						texto = fi.elementAt(j).toString();
						System.out
								.println("exception en escribir, texto = fi.element(j).toStrig() "
										+ texto);
					}

					lineas[fila] = texto;
					fila++;
//					System.out.println(texto);
					texto = new String("");
				}

			}

			return escribir(lineas);
		} catch (Exception e) {
			return new String(
					"Ocurrio un error mientras se escribia el archivo de formulacion");
		}
	}

	private String escribir(String[] lineas) {
		BufferedWriter buffer = null;
		FileWriter fptrw = null;
		File file = null;
		try {
			String path = Constantes.PathArchivos.getDirectorioTemporal()
					+ Constantes.PathArchivos.FILEINSIMPLEX;
			file = new File(path);
			fptrw = new FileWriter(path);
			buffer = new BufferedWriter(fptrw);

			if (lineas != null) {
				buffer.write("hola fecha");
				buffer.newLine();
				for (int i = 0; i < lineas.length; i++) {
					String linea = (String) lineas[i];
					if (!linea.equalsIgnoreCase("")) {

						buffer.write(linea);
						buffer.flush();
						buffer.newLine();
					}
				}
			}

		} catch (IOException e) {
			return "Ocurrio un error escrinbiendo el archivo de formulacion";
		} finally {
			if (buffer != null) {
				try {
					buffer.close();
				} catch (IOException e) {

					return "Ocurrio un error cerrando el archivo de formulacion";
				}
			}

		}

		return null;
	}
	


}
